<template>
  <div>
    <el-page-header
      @back="goTo(route.query.redirect)"
      content="发票查验"
      :size="'mini'"
    >
    </el-page-header>
    <el-button-group style="margin-top: 20px">
      <el-button
        type="primary"
        icon="el-icon-edit"
        plain
        @click="showManual = true"
        >手动录入</el-button
      >
      <el-button
        type="primary"
        icon="el-icon-connection"
        plain
        @click="showAuto = true"
        >自动读取</el-button
      >
    </el-button-group>
    <el-row>
      <el-col :span="24" style="text-align: right">
        <el-button
          type="primary"
          :size="'mini'"
          v-loading="downloadloading"
          @click="
            DownloadInvDetail((state) => {
              downloadloading = state;
            })
          "
          v-if="invInfo.length > 0"
          >导出表格</el-button
        ><el-button
          type="primary"
          :size="'mini'"
          v-loading="downloadloading"
          @click="
            DownloadImageBatch((state) => {
              downloadloading = state;
            })
          "
          v-if="invInfo.length > 0"
          >导出截图</el-button
        >
        <el-button
          type="primary"
          :size="'mini'"
          @click="goTo('/invoice/info/all', route.fullPath)"
          >我的发票</el-button
        ></el-col
      ></el-row
    >
    <el-table
      border
      :data="invInfo"
      :row-class-name="tableRowClassName"
      style="width: 100%"
      id="invDetailTable"
    >
      <el-table-column type="index" />
      <el-table-column prop="invCode" label="发票代码" sortable />
      <el-table-column prop="invNum" label="发票号码" sortable />
      <el-table-column prop="invDate" label="开票日期" sortable />
      <el-table-column prop="invChk" label="校验码" sortable />
      <el-table-column prop="invMoney" label="开具金额" sortable />
      <el-table-column label="备注">
        <template #default="scope">
          <span>{{ scope.row.invTip }}</span>
          <i
            class="el-icon-loading"
            v-if="scope.row.invTip.indexOf('正在查验') !== -1"
          ></i>
          <i
            class="el-icon-loading"
            v-else-if="scope.row.invTip.indexOf('解析成功') !== -1"
          ></i>
          <i
            class="el-icon-check"
            v-else-if="scope.row.invTip === '查验成功'"
          ></i>
          <i class="el-icon-close" v-else></i>
        </template>
      </el-table-column>
      <el-table-column
        label="查看"
        width="100"
        :fixed="isMobile() ? false : 'right'"
      >
        <template #default="scope">
          <el-button
            @click="viewDetail(scope.row)"
            type="text"
            size="small"
            v-if="scope.row.invTip === '查验成功'"
            >详情</el-button
          >
          <el-button
            @click="viewScreenShot(scope.row)"
            type="text"
            size="small"
            v-if="scope.row.invTip === '查验成功'"
            >截图</el-button
          >
          <el-button
            @click="submitInvCheckTask(scope.row)"
            type="text"
            size="small"
            v-else-if="scope.row.invTip.indexOf('正在查验') === -1"
            >重试</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <!-- 手动录入 -->
    <el-dialog
      title="录入发票信息"
      v-model="showManual"
      :width="isMobile() ? '100%' : '450px'"
    >
      <el-form
        ref="invRef"
        :model="invForm"
        status-icon
        :rules="invRules"
        class="invForm"
      >
        <el-form-item label="发票代码" prop="invCode">
          <el-input
            v-model="invForm.invCode"
            placeholder="输入发票代码"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="发票号码" prop="invNum">
          <el-input
            v-model="invForm.invNum"
            placeholder="输入发票代码"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="开票日期" prop="invDate">
          <el-date-picker
            v-model="invForm.invDate"
            type="date"
            placeholder="选择开票日期"
            format="YYYYMMDD"
            value-format="YYYYMMDD"
            style="width: 100%"
          ></el-date-picker>
        </el-form-item>
        <el-form-item label="校验码" prop="invChk">
          <el-input
            v-model="invForm.invChk"
            autocomplete="off"
            placeholder="普票填写校验码后六位"
          ></el-input>
        </el-form-item>
        <el-form-item label="开具金额" prop="invMoney">
          <el-input
            v-model="invForm.invMoney"
            autocomplete="off"
            placeholder="专票填写开具金额"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm('manual')"
            >查验</el-button
          >
          <el-button @click="resetForm('manual')">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
    <!-- 自动录入 -->
    <el-dialog
      title="选择要查验的发票"
      v-model="showAuto"
      :width="isMobile() ? '100%' : '60%'"
    >
      <div v-loading="invListloading" v-if="invState.invList.length">
        <el-checkbox
          v-model="invState.checkAll"
          :indeterminate="invState.isIndeterminate"
          @change="handleCheckAllChange"
          >全选</el-checkbox
        >
        <el-checkbox-group
          :min="invState.min"
          :max="invState.max"
          v-model="invState.checkedInvList"
          @change="handleCheckedInvChange"
        >
          <el-row :gutter="'20'">
            <el-col
              :xs="24"
              :md="12"
              style="margin-top: 10px"
              v-for="(inv, index) in invState.invList"
              :key="index"
            >
              <el-checkbox :label="index" border
                >发票代码:{{ inv.invCode }}&#9;发票号码:{{
                  inv.invNum
                }}</el-checkbox
              >
            </el-col>
          </el-row>
        </el-checkbox-group>
        <el-divider></el-divider>
        <el-button type="primary" @click="submitForm('auto')">查验</el-button>
        <el-button @click="resetForm('auto')">取消</el-button>
      </div>
      <el-empty description="没有需要查验的发票~" v-else></el-empty>
    </el-dialog>

    <!--发票详情查看-->
    <el-dialog
      title="发票详情"
      v-model="showInvDetail"
      :width="isMobile() ? '100%' : '60%'"
    >
      <el-table :data="invDetail" stripe border>
        <el-table-column property="key" label="字段" sortable />
        <el-table-column property="value" label="值" sortable fixed="right" />
      </el-table>
    </el-dialog>
    <!-- 发票截图查看 -->
    <el-dialog
      title="查验截图"
      v-model="showInvCapture"
      :width="isMobile() ? '100%' : '60%'"
    >
      <el-image :src="invCaptureUrl" :fit="'contain'"></el-image>
    </el-dialog>
  </div>
</template>

<script>
import { computed, onMounted, reactive, ref, toRefs, watch } from "vue";
import { useRoute } from "vue-router";
import { useStore } from "vuex";
import { ElNotification } from "element-plus";

import { ApiSubmitInvCheck } from "@/http/api";
import { isMobile, goTo } from "@/libs/utils";
import { GetInvNum, GetInvDataBatch, LoopGetInvCheckData } from "@/libs/data";
import {
  DownloadAsExcelFile,
  DownloadImageBatch,
  DownloadInvDetail,
} from "@/libs/download";

export default {
  setup() {
    const store = useStore();
    const route = useRoute();
    const showInvDetail = ref(false);
    const showInvCapture = ref(false);
    const showManual = ref(false);
    const showAuto = ref(false);
    const invCaptureUrl = ref(null);
    const invRef = ref();
    const invDetail = reactive([]);
    const invListloading = ref(true);
    const downloadloading = ref(false);
    const invInfo = reactive([]);
    const { invNum, invList } = toRefs(store.state);
    const invState = reactive({
      checkAll: false,
      checkedInvList: [],
      invList: computed(() => {
        return invList.value.filter((x) => {
          return (
            x.status &&
            x.invMoney.toString().indexOf("￥") === -1 &&
            x.invTip !== "解析失败" &&
            x.invTip !== "查验成功" &&
            x.invTip !== "重复记录"
          );
        });
      }),
      isIndeterminate: true,
      min: 1,
      max: 10,
    });
    //不包含在显示列表中的字段
    const exceptKeys = [
      "invCode",
      "invNum",
      "invDate",
      "invChk",
      "invMoney",
      "invTip",
      "url",
      "loading",
      "code",
      "status",
    ];
    //手动提交表单
    const invForm = reactive({
      invCode: "",
      invNum: "",
      invDate: "",
      invChk: "",
      invMoney: "",
    });
    const invRules = reactive({
      invCode: [
        { required: true, message: "发票代码必填!", trigger: "blur" },
        {
          validator: (rule, value, callback) => {
            if (/^\d{10}|\d{12}$/.test(value)) {
              callback();
            }
            callback(new Error("发票代码必须是10位或12位数字!"));
          },
          trigger: "blur",
        },
      ],
      invNum: [
        {
          required: true,
          validator: (rule, value, callback) => {
            if (/^\d{8}$/.test(value)) {
              callback();
            }
            callback(new Error("发票号码必须是8位数字!"));
          },
          trigger: "blur",
        },
      ],
      invDate: [
        {
          required: true,
          message: "请选择开票日期!",
          trigger: "blur",
        },
      ],
      invChk: [
        {
          required: false,
          validator: (rule, value, callback) => {
            if (/^\d{6}$/.test(value) || value === "") {
              callback();
            }
            callback(new Error("校验码后六位!"));
          },
          trigger: "blur",
        },
      ],
      invMoney: [
        {
          required: false,
          validator: (rule, value, callback) => {
            if (/^\d+\.\d+$/.test(value) || value === "") {
              callback();
            }
            callback(new Error("开具金额必须是小数!"));
          },
          trigger: "blur",
        },
      ],
    });

    //监听showAuto状态，当打开时去执行下载任务
    watch(showAuto, () => {
      if (showAuto.value) {
        ElNotification.info("一次最多选择10张发票!");
        GetInvNum((state) => {
          invListloading.value = state;
        });
      }
    });
    //监听invNum，当变化时自动加载数据
    watch(invNum, () => {
      GetInvDataBatch((state) => {
        invListloading.value = state;
      });
    });
    onMounted(() => {
      ElNotification.warning("每份￥0.1，已存在或失败不计费!!!");
      setTimeout(() => {
        ElNotification.warning("查验如遇失败，可多试几次!!!");
      }, 1000);
    });
    //表格行状态更新
    const tableRowClassName = ({ row }) => {
      if (row.invTip.indexOf("正在查验") !== -1) return "checking";
      else if (row.invTip.indexOf("解析成功") !== -1) return "checking";
      else if (row.invTip === "查验成功") return "succeed";
      else return "failed";
    };

    //查看发票信息
    const viewDetail = (row) => {
      if (invDetail.length > 0) {
        invDetail.length = 0;
      }
      const rowIdx = utilGetRowIdx(row, 2);
      const invRow = invList.value[rowIdx];
      for (let keyval in invRow) {
        if (exceptKeys.indexOf(keyval) === -1) {
          //只有不排除的字段才会加入
          invDetail.push({ key: keyval, value: invRow[keyval] });
        }
      }
      showInvDetail.value = true;
    };
    //查验截图
    const viewScreenShot = (row) => {
      const rowIdx = utilGetRowIdx(row, 2);
      invCaptureUrl.value = invList.value[rowIdx].url;
      showInvCapture.value = true;
    };
    //获取行号
    const utilGetRowIdx = (row, source = 1) => {
      let invObjList = source === 1 ? invInfo : invList.value;
      for (let idx in invObjList) {
        if (
          invObjList[idx].invCode === row.invCode &&
          invObjList[idx].invNum === row.invNum
        )
          return idx;
      }
      return -1;
    };
    //提交发票查验任务
    const submitInvCheckTask = (row) => {
      let rowIdx = utilGetRowIdx(row);
      if (rowIdx === -1) {
        ElNotification.error("找不到数据!");
        return;
      }
      invInfo[rowIdx]["invTip"] = "正在查验";
      ApiSubmitInvCheck({
        inv_code: row.invCode,
        inv_num: row.invNum,
        inv_date: row.invDate,
        inv_chk: row.invChk,
        inv_money: row.invMoney ? row.invMoney.toFixed(2) : row.invMoney,
      }).then((res) => {
        if (res.code === 2000) {
          ElNotification.success("已提交查验任务!");
          LoopGetInvCheckData(row.invCode, row.invNum, (key, val) => {
            invInfo[rowIdx][key] = val;
          });
          if (invRef.value) invRef.value.resetFields();
        } else {
          ElNotification.error(`任务提交失败:${res.message}!`);
          invInfo[rowIdx]["invTip"] = "任务提交失败!";
        }
      });
    };
    const submitForm = (method) => {
      if (method === "manual") {
        invRef.value.validate((valid) => {
          if (valid) {
            const inv = {
              invCode: invForm.invCode,
              invNum: invForm.invNum,
              invDate: invForm.invDate,
              invChk: invForm.invChk,
              invMoney: invForm.invMoney,
              invTip: "正在查验",
            };
            invInfo.push(inv);
            submitInvCheckTask(invForm);
            showManual.value = false;
          } else {
            return false;
          }
        });
      } else if (method === "auto") {
        if (invState.checkedInvList.length < 1) {
          ElNotification.warning("至少选择一条记录!");
          return false;
        }
        //当前约可用数
        const accessMoneyNum = parseInt(store.state.userInfo.amount * 10);
        //选择的数目
        const checkedNum = invState.checkedInvList.length;
        if (accessMoneyNum < checkedNum) {
          ElNotification.warning(`当前余额最多可支持查验${accessMoneyNum}张!`);
          return false;
        }
        for (let idx in invState.checkedInvList) {
          const inv = invState.invList[idx];
          invInfo.push(inv);
          submitInvCheckTask(inv);
        }
        showAuto.value = false;
        invState.checkedInvList = [];
      }
    };
    const resetForm = (method) => {
      if (method === "manual") {
        invRef.value.resetFields();
        showManual.value = false;
      } else if (method === "auto") {
        showAuto.value = false;
        invState.checkedInvList = [];
      }
    };
    //全选状态管理
    const handleCheckAllChange = (val) => {
      invState.checkedInvList = val
        ? [...new Array(invState.invList.length).keys()]
        : [];
      invState.isIndeterminate = false;
    };
    const handleCheckedInvChange = (value) => {
      const checkedCount = value.length;
      invState.checkAll = checkedCount === invState.invList.length;
      invState.isIndeterminate =
        checkedCount > 0 && checkedCount < invState.invList.length;
    };
    return {
      route,
      invRef,
      invListloading,
      downloadloading,
      invList,
      invInfo,
      invDetail,
      invState,
      showAuto,
      showInvDetail,
      showInvCapture,
      showManual,
      invCaptureUrl,
      goTo,
      tableRowClassName,
      viewDetail,
      viewScreenShot,
      invForm,
      invRules,
      resetForm,
      submitForm,
      isMobile,
      handleCheckAllChange,
      handleCheckedInvChange,
      DownloadAsExcelFile,
      DownloadImageBatch,
      DownloadInvDetail,
      submitInvCheckTask,
    };
  },
};
</script>

<style>
.el-table .checking {
  color: rgb(187, 180, 180);
}

.el-table .failed {
  background: oldlace;
  color: #f56c6c;
}

.el-table .succeed {
  background: #f0f9eb;
  color: #67c23a;
}
</style>